﻿using System;
using System.Runtime.InteropServices;

namespace USNetFramework.Network
{
    public enum EnumRequestType
    {
        Request = 1,    // 请求
        Response,       // 回应
    }

    /// <summary>
    /// 加密类型
    /// </summary>
    public enum EnumEncryptType
    {
        Null,           // 不使用加密
        XXTea,          // XXTea加密
        Aes,            // Aes加密
    }

    /// <summary>
    /// 压缩类型
    /// </summary>
    public enum EnumCompressType
    {
        Null,
    }


    /// <summary>
    /// 扩展网络包头数据，实际消息的字节流格式如下：
    /// <para>    * +------------+-------------+-------------+</para>
    /// <para>    * |  消息长度   |  加密类型    |  压缩类型    |</para>
    /// <para>    * |   2byte    |   1byte     |   1byte     |</para>
    /// <para>    * +------------+-------------+-------------+</para>
    /// </summary>
    /// 
    [System.Serializable]
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct NetHeadEx
    {
        public ushort  m_usNetSize;
        public byte    m_bEncryptType;
        public byte    m_bCompressType;
    }


    /// <summary>
    /// 发送网络包数据，实际消息的字节流格式如下：
    /// <para>    * +-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+</para>
    /// <para>    * |  扩展包头    |   包长度     |  请求类型    |   会话ID     |  协议类型    |  协议ID      |  内容长度    |    内容     |</para>
    /// <para>    * |   4byte     |    2byte    |   1byte     |   4byte     |   2byte     |   2byte     |    2byte    |    ABCD     |</para>
    /// <para>    * +-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+</para>
    /// </summary>
    public class NetPacket
    {
        /// <summary>
        /// 网络长度
        /// </summary>
        public static ushort NetPacketLenSize = 2;


        /// <summary>
        /// 包头长度
        /// </summary>
        public unsafe static ushort HeadExSize = (ushort)sizeof(NetHeadEx);


        /// <summary>
        /// 初始长度
        /// </summary>
        private const ushort InitSize = sizeof(byte) + sizeof(uint) + (sizeof(ushort) * 3);


        /// <summary>
        /// 网络包头
        /// </summary>
        private NetHeadEx m_objHeadEx;


        /// <summary>
        /// 网络字节流长度
        /// </summary>
        public ushort NetSize
        {
            get
            {
                return this.m_objHeadEx.m_usNetSize;
            }

            set
            {
                this.m_objHeadEx.m_usNetSize = value;
            }
        }


        /// <summary>
        /// 加密类型
        /// </summary>
        public byte EncryptType
        {
            get
            {
                return this.m_objHeadEx.m_bEncryptType;
            }

            set
            {
                this.m_objHeadEx.m_bEncryptType = value;
            }
        }


        /// <summary>
        /// 压缩类型
        /// </summary>
        public byte CompressType
        {
            get
            {
                return this.m_objHeadEx.m_bCompressType;
            }

            set
            {
                this.m_objHeadEx.m_bCompressType = value;
            }
        }


        /// <summary>
        /// 网络包长度
        /// </summary>
        public ushort TotalSize
        {
            get;
            private set;
        }


        /// <summary>
        /// 请求类型
        /// </summary>
        public EnumRequestType RequestType
        {
            get;
            set;
        }


        /// <summary>
        /// 协议类型
        /// </summary>
        public uint SessionID
        {
            get;
            set;
        }


        /// <summary>
        /// 协议类型
        /// </summary>
        public ushort ProtoType
        {
            get;
            set;
        }

        
        /// <summary>
        /// 协议ID
        /// </summary>
        public ushort ProtoID
        {
            get;
            set;
        }

        
        /// <summary>
        /// 数据长度
        /// </summary>
        public ushort DataSize
        {
            get;
            private set;
        }

        
        /// <summary>
        /// 数据内容
        /// </summary>
        private byte[] m_buffer;
        public byte[] DataBuffer
        {
            set
            {
                if (null == value)
                {
                    return;
                }
                if (null != this.m_buffer)
                {
                    this.TotalSize -= (ushort)(DataSize + sizeof(ushort));
                }
                this.m_buffer = value;
                DataSize = (ushort)value.Length;
                this.TotalSize += (ushort)(DataSize + sizeof(ushort));
            }
            get
            {
                return m_buffer;
            }
        }


        /// <summary>
        /// 构建一个空的网络包
        /// </summary>
        public NetPacket()
        {   
            this.Init();
        }


        /// <summary>
        /// 构建一个指定协议的网络包
        /// </summary>
        /// <param name="inProtoType">协议类型</param>
        /// <param name="inProtoID">协议ID</param>
        public NetPacket(ushort inProtoType, ushort inProtoID)
        {
            this.Init();
            this.ProtoType = inProtoType;
            this.ProtoID = inProtoID;
        }


        /// <summary>
        /// 初始化
        /// </summary>
        private void Init()
        {
            this.TotalSize = InitSize;
            this.RequestType = EnumRequestType.Request;
            this.SessionID = 0;
            this.ProtoType = 0;
            this.ProtoID = 0;
        }
    }
}
